import fse from 'fs-extra';
import path from 'path';

import { ModuleTemplateOption, ProjectTemplateIndex } from '../models/model-options';
import { moduleBuilder, ModuleCreator } from '../module-builder';
import { ModulesOption, projectBuilder, ProjectCreator } from '../project-builder';

export function requireAll(source: string) {
  const stats = fse.statSync(source);

  if (stats.isDirectory()) {
    const children = fse.readdirSync(source);
    for (const child of children) {
      requireAll(path.join(source, child));
    }
  } else {
    if (source.endsWith('.ts') && !source.endsWith('.d.ts')) {
      require(source);
    }
  }
}

// 加载modules
const moduleTemplatePath = path.join(__dirname, 'module-template');
requireAll(moduleTemplatePath);

// 加载Project
const projectTemplatePath = path.join(__dirname, 'project-template');
requireAll(projectTemplatePath);

/**
 * 默认module模板
 *
 * @param {ModuleTemplateOption} option
 * @return {(moduleName: string) => Module}
 * @constructor
 */
const DefaultModule: (option: ModuleTemplateOption) => ModuleCreator = (option) => {
  const creator = moduleBuilder.findModuleCreator(option);
  if (creator === undefined) {
    throw new Error('The corresponding default template was not found.');
  }
  return creator;
};

/**
 * 默认project模板
 *
 * @param {ProjectTemplateIndex} index
 * @param modulesOption
 * @return {(project: string) => Project}
 * @constructor
 */
const DefaultProject: (index: ProjectTemplateIndex, modulesOption?: ModulesOption) => ProjectCreator =
  (index: ProjectTemplateIndex, modulesOption): ProjectCreator => {
    const creator = projectBuilder.findProjectCreator(index, modulesOption);
    if (creator === undefined) {
      throw new Error(`The corresponding default template was not found: ${JSON.stringify(index)}`);
    }
    return creator;
  };

export const DefaultTemplate = {
  module: DefaultModule,
  project: DefaultProject
};
